package com.wang.config.security;

import com.wang.domain.enums.UserRoleEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsUtils;


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final JWTAuthenticationFilter jwtAuthenticationFilter;
    private final RestAccessDeniedHandler restAccessDeniedHandler;
    private final RestAuthenticationSuccessHandler restAuthenticationSuccessHandler;
    private final RestAuthenticationFailureHandler restAuthenticationFailureHandler;
    private final RestLoginAuthenticationEntryPoint restLoginAuthenticationEntryPoint;

    @Autowired
    public SecurityConfig(JWTAuthenticationFilter jwtAuthenticationFilter, RestAccessDeniedHandler restAccessDeniedHandler, RestAuthenticationSuccessHandler restAuthenticationSuccessHandler, RestAuthenticationFailureHandler restAuthenticationFailureHandler, RestLoginAuthenticationEntryPoint restLoginAuthenticationEntryPoint) throws Exception {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
        this.restAccessDeniedHandler = restAccessDeniedHandler;
        this.restAuthenticationSuccessHandler = restAuthenticationSuccessHandler;
        this.restAuthenticationFailureHandler = restAuthenticationFailureHandler;
        this.restLoginAuthenticationEntryPoint = restLoginAuthenticationEntryPoint;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 关闭csrf
        http.cors()
                .and().headers().frameOptions().disable()
                .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .and().csrf().disable()

                .logout()
                .logoutUrl("/td/api/user/logout")
                .and()
                // 未登录访问处理
                .httpBasic().authenticationEntryPoint(restLoginAuthenticationEntryPoint)
                .and()
                .formLogin()
                // 用户登录调用的接口
                .loginProcessingUrl("/td/api/user/login")
                // 登录成功处理
                .successHandler(restAuthenticationSuccessHandler)
                // 登录失败处理
                .failureHandler(restAuthenticationFailureHandler)
                .permitAll()
                .and()
                .exceptionHandling()
                // 无权限访问接口处理
                .accessDeniedHandler(restAccessDeniedHandler)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 权限设置
                // 只有管理员身份可以访问管理员接口
                .antMatchers("/td/api/admin/**").hasRole(UserRoleEnum.ADMIN.getName())

                // 所有人都能访问
                .antMatchers("/td/api/user/**").permitAll()

                .antMatchers("/*.svg","/*.png","/*.js","/*.css").permitAll()
                //忽略swagger访问权限限制
                .antMatchers(
                        "/userlogin",
                        "/userlogout",
                        "/userjwt",
                        "/v2/api-docs",
                        "/swagger-resources/configuration/ui",
                        "/swagger-resources",
                        "/swagger-resources/configuration/security",
                        "/swagger-ui.html",
                        "/doc.html",
                        "/css/**",
                        "/js/**",
                        "/images/**",
                        "/webjars/**",
                        "/import/test",
                        "**/favicon.ico",
                        "/index").permitAll()

                .anyRequest().authenticated()
                .and()
                // 自定义jwt验证过滤器
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .headers().cacheControl();
    }
}
